<template>
  <div class="containers" ref="content" v-loading="loading">
    <div class="process-type">
      <template v-for="item in processType">
        <div :class="item.className" :key="item.className"></div>
        <span :key="item.name">{{ item.name }}</span>
      </template>
    </div>
    <div class="canvas" ref="canvas" id="bpmnCanvas"></div>
  </div>
</template>
<script>
import {
  getProDefineXml,
  getHighLine,
} from "@/api/internalApproval/myApplication.js";
import BpmnViewer from "bpmn-js";
import {
  append as svgAppend,
  attr as svgAttr,
  create as svgCreate,
} from "tiny-svg";
import { query as domQuery } from "min-dom";
export default {
  components: {},
  data() {
    return {
      bpmnModeler: null,
      canvas: null,
      loading: false,
      processType: [
        {
          className: "process-pass",
          name: "已通过任务",
        },
        {
          className: "process-wait",
          name: "待审批任务",
        },
        {
          className: "process-delay",
          name: "办理超时任务",
        },
        {
          className: "process-start",
          name: "未开始任务",
        },
      ],
    };
  },
  props: {
    type: {
      type: Number,
      default: 0,
    },
    detail: {
      type: Object,
      required: true,
      default() {
        return {};
      },
    },
  },
  methods: {
    // 渲染流程图高亮
    async getHighLine() {
      const result = await getHighLine({
        instanceId: this.detail.id
          ? this.detail.id
          : this.detail.processInstanceId,
      });
      this.getProDefineXml(result.data);
    },
    // 获取高亮流程定义xml
    async getProDefineXml(highLineData) {
      let result = await getProDefineXml({
        processDefinitionId: this.detail.processDefinitionId,
      });
      let that = this;
      that.bpmnModeler.importXML(result);
      that.$nextTick(() => {
        const canvas = this.bpmnModeler.get("canvas");
        canvas.zoom("fit-viewport", "auto");
        // 设置高亮线和高亮节点
        const nodeCodes = highLineData.highPoint;
        const colorClass = "nodeSuccess";
        that.setNodeColor(nodeCodes, colorClass, canvas);
        const nodeCodes2 = highLineData.highLine;
        const colorClass2 = "lineSuccess";
        that.setNodeColor(nodeCodes2, colorClass2, canvas);
        // 过期节点判断
        if (highLineData.delay) {
          const nodeCodes4 = highLineData.delay;
          const colorClass4 = "delayProcess";
          that.setNodeColor(nodeCodes4, colorClass4, canvas);
        } else {
          // 设置办理中的节点
          const nodeCodes3 = highLineData.waitingToDo;
          const colorClass3 = "process";
          that.setNodeColor(nodeCodes3, colorClass3, canvas);
        }
        // 修改图箭头的的颜色
        const marker = svgCreate("marker");
        svgAttr(marker, {
          id: "sequenceflow-arrow-normal",
          viewBox: "0 0 10 20",
          refX: "11",
          refY: "10",
          markerWidth: "10",
          markerHeight: "10",
          orient: "auto",
        });
        const path = svgCreate("path");
        svgAttr(path, {
          d: "M 1 5 L 11 10 L 1 15 Z",
          style:
            "stroke:green;stroke-width: 1px; stroke-linecap: round; stroke-dasharray: 10000, 1; fill:green",
        });
        const defs = domQuery("defs");
        svgAppend(marker, path);
        svgAppend(defs, marker);
        setTimeout(() => {
          that.loading = false;
        }, 300);
      });
      return;
    },
    // 获取默认流程定义
    async getProXml() {
      const result = await getProDefineXml({
        processDefinitionId: this.detail.processDefinitionId,
      });
      let that = this;
      try {
        that.bpmnModeler.importXML(result);
      } catch (err) {
        console.log(err);
      }
      setTimeout(() => {
        that.loading = false;
      }, 300);
    },
    // 给已经走过的流程添加颜色
    setNodeColor(nodeCodes, colorClass, canvas) {
      for (let i = 0; i < nodeCodes.length; i++) {
        if (nodeCodes[i]) {
          canvas.addMarker(nodeCodes[i], colorClass);
        }
      }
    },
  },
  mounted() {
    let canvas = this.$refs.canvas;
    this.bpmnModeler = new BpmnViewer({
      container: canvas,
      height: 200,
      width: 700,
    });
    // type==0  实例管理查看流程图 type==1  流程查看
    if (this.type == 0) {
      this.getHighLine();
    } else {
      this.getProXml();
    }
  },
};
</script>
<style lang="scss">
.containers {
  position: relative;
  display: inline-block;
  padding: 20px 0 0 20px;
  width: 100%;
  height: 100%;
  background-color: #fff;
}
.process-type {
  position: absolute;
  top: 1px;
  display: flex;
  align-items: center;
  color: #474747;
}
.common-process {
  margin: 0 5px;
  width: 30px;
  height: 15px;
}
.process-pass {
  @extend .common-process;
  background-color: green;
}
.process-wait {
  @extend .common-process;
  background-color: orange;
}
.process-delay {
  @extend .common-process;
  background-color: red;
}
.process-start {
  @extend .common-process;
  background-color: #292929;
}
.canvas {
  width: 100%;
  height: 100%;
  overflow: auto;
}
.nodeSuccess:not(.djs-connection) .djs-visual > :nth-child(1) {
  stroke: green !important;
  stroke-width: 3px;
}
.nodeSuccess:not(.djs-connection) .djs-visual > :nth-child(2) {
  // stroke: green !important;
  //fill: green !important;
}

.nodeError:not(.djs-connection) .djs-visual > :nth-child(1) {
  stroke: red !important;
  stroke-width: 3px;
}

.lineSuccess:not(.djs-shape) .djs-visual :last-child {
  stroke: green !important;
  marker-end: url(#sequenceflow-arrow-normal) !important;
}

.process:not(.djs-connection) .djs-visual > :nth-child(1) {
  stroke: orange !important;
}
.delayProcess:not(.djs-connection) .djs-visual > :nth-child(1) {
  stroke: red !important;
}
.lineError:not(.djs-shape) .djs-visual :last-child {
  stroke: red !important;
}
.bjs-powered-by {
  display: none !important;
}
</style>
